package com.lixin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lixin.entity.Comments;
import com.lixin.entity.Friendships;
import com.lixin.entity.Likes;
import com.lixin.entity.Posts;
import com.lixin.mapper.PostsMapper;
import com.lixin.model.response.PostsResponse;
import com.lixin.service.ICommentsService;
import com.lixin.service.IFriendshipsService;
import com.lixin.service.ILikesService;
import com.lixin.service.IPostsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 用于存储用户的动态内容 服务实现类
 * </p>
 *
 * @author lixin
 * @since 2023-07-28
 */
@Service
public class PostsServiceImpl extends ServiceImpl<PostsMapper, Posts> implements IPostsService {

    private static final Integer CUR=0;
    private static final Integer PAGE_SIZE=10;

    @Autowired
    private IFriendshipsService iFriendshipsService;

    @Autowired
    private ILikesService likesService;

    @Autowired
    private ICommentsService commentsService;

    @Override
    public Posts addOrUpdate(Posts posts) {
        Date now = new Date();
        if (posts.getPostId() == null) {
            posts.setTimestamp(now);
            this.baseMapper.insert(posts);
        } else {
            this.baseMapper.updateById(posts);
        }
        return posts;
    }

    /**
     * 分页查询 如果没有传递id说明是刚打开朋友圈或者是刷新的动作
     * 如果传递了id 说明是要获取当前id往前的最新的10条数据
     * 用id做标识是为了减少偏移量 避免深度分页
     * 这里没有仿照微信只展示朋友信息而是跟qq一样会展示所有留言的信息
     * @param userId           用户ID
     * @param lastViewedPostId 当前帖子ID，用于翻页，获取比该ID小的帖子
     * @return
     */
    @Override
    public List<Posts> postList(Integer userId, Integer lastViewedPostId) {
        List<Posts> posts = postListQuery(userId, lastViewedPostId);
        List<PostsResponse> postsResponses = BeanUtil.copyToList(posts, PostsResponse.class);
        List<Integer> postIds = posts.stream().map(Posts::getPostId).toList();
        List<Likes> likes = likesService.selectLikesByPostIds(postIds);
        List<Comments> comments = commentsService.selectByPostIds(postIds);
        mergePost(likes, comments, postsResponses);
        return posts;
    }

    private void mergePost(List<Likes> likes, List<Comments> comments, List<PostsResponse> postsResponses) {
        Map<Integer, List<Likes>> likesMap = likes.stream().collect(Collectors.groupingBy(Likes::getPostId));
        Map<Integer, List<Comments>> commentsMap = comments.stream().collect(Collectors.groupingBy(Comments::getPostId));
        for (PostsResponse postsResponse : postsResponses) {
            Integer postId = postsResponse.getPostId();
            postsResponse.setComments(commentsMap.get(postId));
            postsResponse.setLikes(likesMap.get(postId));
        }
    }
    public List<Posts> postListQuery(Integer userId, Integer lastViewedPostId) {
        List<Friendships> allFriends = iFriendshipsService.findAllFriendsQuery(userId);
        List<Integer> friendsIds = allFriends.stream().map(Friendships::getFriendId).toList();
        LambdaQueryChainWrapper<Posts> postsWrapper = this.lambdaQuery().in(Posts::getUserId, friendsIds).orderByDesc(Posts::getTimestamp);
        if (lastViewedPostId != null) {
            postsWrapper.lt(Posts::getPostId, lastViewedPostId);
        }
        postsWrapper.page(new Page<>(CUR, PAGE_SIZE));
        return postsWrapper.list();
    }
}
